package io.leo.leoutils.functional;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import io.leo.leoutils.StringUtils;
public class LeoActivity extends AppCompatActivity {

    private final static String TAG="LeoActivity";

    private final static int PERMISSION_REQ_CODE=1;
    private Consumer<String> onDisallow;

    private String[] permissions=null;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    /**
     * 初始化控件，如果您使用了@BV或者任何关于LeoActivity控件的功能，您都必须要在Activity里写这个方法，并且您可以在这里给控件赋予默认值，如果不需要的话，以下是最简写法：
     * initView(()->{});
     * @param n 用于初始化的函数接口
     * @return
     */
    public LeoActivity initView(NoParamNoRet n){
        Field[] fields = getClass().getFields();
        for (Field f:fields){
            BV bv = f.getAnnotation(BV.class);
            OnClick onClick = f.getAnnotation(OnClick.class);
            if (bv==null)continue;
            try {
                View view = findViewById(bv.value());
                f.set(this,view);
                if (onClick!=null&&!StringUtils.isEmpty(onClick.value())){
                    Method realOnclickMethod = getClass().getMethod(onClick.value(),View.class);
                    view.setClickable(true);
                    view.setOnClickListener(v-> {
                        try {
                            realOnclickMethod.invoke(this,v);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException("调用 "+onClick.value()+"(View view) 方法出现错误："+e.getMessage());
                        } catch (InvocationTargetException e) {
                            throw new RuntimeException("调用 "+onClick.value()+"(View view) 方法出现错误："+e.getMessage());
                        }
                    });
                }
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("在 "+getClass().getSimpleName()+" 中没有 "+onClick.value()+"(View view) 方法！");
            } catch (IllegalAccessException e) {
                throw new RuntimeException("自动绑定View时出现问题："+e.getMessage());
            }
        }
        n.exec();
        return this;
    }

    /**
     * 初始化数据的方法，此方法并无任何实际功能，只是为了规范继承自LeoActivity的所有Activity的编程风格。
     * @param n 初始化数据的地方
     * @return
     */
    public LeoActivity initData(NoParamNoRet n){
        n.exec();
        return this;
    }

    /**
     * 检测权限，如果有未允许的权限则会回调，所以开发者可以这样用：
     * chkPermission(()->{reqPermission(ret->{doSomething})})
     * @param n 其实就是当有未允许的权限时需要进行的操作
     * @return
     */
    public LeoActivity chkPermission(NoParamNoRet n){
        if (getPermissions()==null)
            return this;
        for (String per:getPermissions()){
            if (ContextCompat.checkSelfPermission(this,per)==PackageManager.PERMISSION_DENIED) {
                n.exec();
                break;
            }
        }
        return this;
    }

    /**
     * 请求权限
     * @param onDisallow 如果用户拒绝了权限，那么回调
     * @return
     */
    public LeoActivity reqPermission(Consumer<String> onDisallow){
        this.onDisallow=onDisallow;
        if (getPermissions()==null)return this;
        reqPermission(()-> getPermissions());
        return this;
    }

    /**
     * 请求单个权限
     * @param per 权限
     * @return
     */
    public LeoActivity reqSinglePermission(String per){
        reqPermission(()-> new String[]{per});
        return this;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode==PERMISSION_REQ_CODE){
            for (int i = 0; i < grantResults.length; i++) {
                int grantResult = grantResults[i];
                if (grantResult == PackageManager.PERMISSION_DENIED) {
                    if (onDisallow!=null)
                        onDisallow.accept(permissions[i]);
                }
            }
        }
    }
    /***
     * 请求权限
     * @param supplier 返回权限列表
     * @return
     */
    private LeoActivity reqPermission(Supplier<String[]> supplier){
        ActivityCompat.requestPermissions(this,supplier.get(),PERMISSION_REQ_CODE);
        return this;
    }
    private String[] getPermissions(){
        if (permissions!=null)return permissions;
        NeedPermission needPermission = getClass().getAnnotation(NeedPermission.class);
        if (needPermission==null)
            return null;
        return permissions=needPermission.value();
    }
}
